﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static System.Threading.Thread;
using static System.Console;

namespace Project_1
{
    /// <summary>
    /// 1.9 向线程传递参数
    /// </summary>
    public class Unit_1_09
    {
        /*
         * 线程传参方式：
         * 1.使用类的构造函数传参
         * 2.使用Thread.Start(object)传参，参数必须是object类型
         * 3.使用lambda表达式传参,var threadThree = new Thread(() => CountNumbers(6));
         * lambda表达式传参，使用相同的变量会涉及到共享变量值的问题
         */
        public static void Go()
        {

            #region 通过类的构造函数传参
            var sample = new ThreadSample(8);

            var threadOne = new Thread(sample.CountNumbers);
            threadOne.Name = "threadOne";
            threadOne.Start();
            threadOne.Join();
            #endregion

            WriteLine("------------");

            #region 通过Start()将传参,必须是object类型
            var threadTwo = new Thread(Count);
            threadTwo.Name = "threadTwo";
            threadTwo.Start(4);
            threadTwo.Join(); 
            #endregion

            WriteLine("------------");

            #region 使用lambda表达式传参
            var threadThree = new Thread(() => CountNumbers(6));
            threadThree.Name = "threadThree";
            threadThree.Start();
            threadThree.Join(); 
            #endregion

            WriteLine("------------");

            #region 这样两个线程会共享变量值，因为在启动之前已将改为20，
            int i = 10;
            var threadFour = new Thread(() => PrintNumber(i));
            i = 20;
            var threadFive = new Thread(() => PrintNumber(i));
            threadFour.Start();
            threadFive.Start(); 
            #endregion
        }

        static void Count(object iterations)
        {
            CountNumbers((int)iterations);
        }

        static void CountNumbers(int iterations)
        {
            for (int i = 1; i < iterations; i++)
            {
                Sleep(TimeSpan.FromSeconds(0.5));
                WriteLine($"线程名：{CurrentThread.Name}，i：{i}");
            }
        }

        static void PrintNumber(int number)
        {
            WriteLine(number);
        }

        class ThreadSample
        {
            private readonly int _iterations;

            public ThreadSample(int iterations)
            {
                _iterations = iterations;
            }

            public void CountNumbers()
            {
                for (int i = 1; i < _iterations; i++)
                {
                    Sleep(TimeSpan.FromSeconds(0.5));
                    WriteLine($"线程名：{CurrentThread.Name}, i: {i}");
                }
            }
        }
    }
}
